package com.cc.visitor.aop;
import com.cc.alltype.BusinessException;
import com.cc.visitor.utils.RequestValidator;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author chanchaw
 * @create 2025-03-15 19:22
 */
@Aspect
@Component
public class SignatureVerificationAspect {
    private static final String SECRET_KEY = "showa";// 请求签名用key

    /**
     * 拦截带有 @VerifySignature 注解的方法
     */
    @Around("@annotation(com.cc.visitor.annotation.VerifySignature)")
    public Object verifySignature(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取当前请求
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        // 1. 提取请求参数 - 读取URL参数和表单参数
        /*
        Map<String, String> params = new HashMap<>();
        request.getParameterMap().forEach((key, values) -> {
            if (values.length > 0) {
                params.put(key, values[0]); // 只取第一个值
            }
        });
        */

        // 1. 提取请求参数 - 读取请求体中的参数
//        Object[] args = joinPoint.getArgs();
//        Map<String, String> params = (Map<String, String>) args[0]; // @RequestBody 参数

        String timestampStr = Optional.ofNullable(request.getHeader("sigTimestamp")).orElse("");
        String ciphertext = Optional.ofNullable(request.getHeader("sigCiphertext")).orElse("");

        // 2. 提取签名
        if (timestampStr.length() == 0 || ciphertext.length() == 0) {
            throw new BusinessException("验证请求签名失败！");
        }

        // 3. 验证签名
        Map<String, String> params = new HashMap<>();
        params.put("timestamp",timestampStr);
        params.put("secretKey",SECRET_KEY);
        boolean isValid = RequestValidator.validateSignature(params, ciphertext, SECRET_KEY);
        if (!isValid) {
            throw new BusinessException("验证请求签名失败!");
        }

        // 4. 如果签名验证通过，继续执行原方法
        return joinPoint.proceed();
    }

    /**
     * 读取请求体
     */
    private String getRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
        }
        return stringBuilder.toString();
    }
}